package com.apestech.framework.util;

import java.lang.reflect.Field;
import java.util.Vector;

import com.apestech.framework.run.core.SingleInstance;
import com.apestech.framework.util.modul.ClassMethod;
import com.esotericsoftware.reflectasm.MethodAccess;

public class ReflectUtil extends StringUtil{

	public static Object getObject(String className) throws Exception{
		return SingleInstance.getInstance(className);
	}

	public static ClassMethod getClassMethods(String className) throws Exception {
		Object obj=getObject(className);
		MethodAccess access = MethodAccess.get(obj.getClass());
		if(access==null) return null;
		return new ClassMethod(access, obj);
	}
	
	public static Object execMethod(Object obj, String methodName, Object... params) throws InstantiationException, IllegalAccessException{
		MethodAccess access = MethodAccess.get(obj.getClass());
		return access.invoke(obj, methodName, params);
	}
	
	public static Object execMethod(String className, String methodName, Object... params) throws Exception{
		Object obj=getObject(className);
		return execMethod(obj, methodName, params);
	}
	
	public static Object execMethod(String className, String methodName, Vector<Object> list) throws Exception{
		Object obj=getObject(className);
		return execMethod(obj, methodName, list);
	}
	
	public static Object execMethod(Object obj, String methodName, Vector<Object> list) throws Exception{
		int len=list.size();
		switch(len){
			case 0:
				return execMethod(obj, methodName);
			case 1:
				return execMethod(obj, methodName, list.get(0));
			case 2:
				return execMethod(obj, methodName, list.get(0), list.get(1));
			case 3:
				return execMethod(obj, methodName, list.get(0), list.get(1), list.get(2));
			case 4:
				return execMethod(obj, methodName, list.get(0), list.get(1), list.get(2), list.get(3));
			case 5:
				return execMethod(obj, methodName, list.get(0), list.get(1), list.get(2), list.get(3), list.get(4));
			case 6:
				return execMethod(obj, methodName, list.get(0), list.get(1), list.get(2), list.get(3), list.get(4), list.get(5));
			case 7:
				return execMethod(obj, methodName, list.get(0), list.get(1), list.get(2), list.get(3), list.get(4), list.get(5), 
						list.get(6));
			case 8:
				return execMethod(obj, methodName, list.get(0), list.get(1), list.get(2), list.get(3), list.get(4), list.get(5), 
						list.get(6), list.get(7));
			case 9:
				return execMethod(obj, methodName, list.get(0), list.get(1), list.get(2), list.get(3), list.get(4), list.get(5), 
						list.get(6), list.get(7), list.get(8));
			case 10:
				return execMethod(obj, methodName, list.get(0), list.get(1), list.get(2), list.get(3), list.get(4), list.get(5), 
						list.get(6), list.get(7), list.get(8), list.get(9));
			case 11:
				return execMethod(obj, methodName, list.get(0), list.get(1), list.get(2), list.get(3), list.get(4), list.get(5), 
						list.get(6), list.get(7), list.get(8), list.get(9), list.get(10));
			case 12:
				return execMethod(obj, methodName, list.get(0), list.get(1), list.get(2), list.get(3), list.get(4), list.get(5), 
						list.get(6), list.get(7), list.get(8), list.get(9), list.get(10), list.get(11));
			case 13:
				return execMethod(obj, methodName, list.get(0), list.get(1), list.get(2), list.get(3), list.get(4), list.get(5), 
						list.get(6), list.get(7), list.get(8), list.get(9), list.get(10), list.get(11), list.get(12));
			case 14:
				return execMethod(obj, methodName, list.get(0), list.get(1), list.get(2), list.get(3), list.get(4), list.get(5), 
						list.get(6), list.get(7), list.get(8), list.get(9), list.get(10), list.get(11), list.get(12), 
						list.get(13));
			case 15:
				return execMethod(obj, methodName, list.get(0), list.get(1), list.get(2), list.get(3), list.get(4), list.get(5), 
						list.get(6), list.get(7), list.get(8), list.get(9), list.get(10), list.get(11), list.get(12), 
						list.get(13),list.get(14));
			case 16:
				return execMethod(obj, methodName, list.get(0), list.get(1), list.get(2), list.get(3), list.get(4), list.get(5), 
						list.get(6), list.get(7), list.get(8), list.get(9), list.get(10), list.get(11), list.get(12), 
						list.get(13),list.get(14),list.get(15));
			case 17:
				return execMethod(obj, methodName, list.get(0), list.get(1), list.get(2), list.get(3), list.get(4), list.get(5), 
						list.get(6), list.get(7), list.get(8), list.get(9), list.get(10), list.get(11), list.get(12), 
						list.get(13),list.get(14),list.get(15),list.get(16));
			case 18:
				return execMethod(obj, methodName, list.get(0), list.get(1), list.get(2), list.get(3), list.get(4), list.get(5), 
						list.get(6), list.get(7), list.get(8), list.get(9), list.get(10), list.get(11), list.get(12), 
						list.get(13),list.get(14),list.get(15),list.get(16),list.get(17));
			case 19:
				return execMethod(obj, methodName, list.get(0), list.get(1), list.get(2), list.get(3), list.get(4), list.get(5), 
						list.get(6), list.get(7), list.get(8), list.get(9), list.get(10), list.get(11), list.get(12), 
						list.get(13),list.get(14),list.get(15),list.get(16),list.get(17),list.get(18));
			case 20:
				return execMethod(obj, methodName, list.get(0), list.get(1), list.get(2), list.get(3), list.get(4), list.get(5), 
						list.get(6), list.get(7), list.get(8), list.get(9), list.get(10), list.get(11), list.get(12), 
						list.get(13),list.get(14),list.get(15),list.get(16),list.get(17),list.get(18),list.get(19));
		}
		return null;
	}

	public static Object getPrivateField(Object instance, String filedName) {
		try {
			Field field = instance.getClass().getDeclaredField(filedName);
			field.setAccessible(true);
			return field.get(instance);
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}
	
}
